
#include "stm32f10x.h"
#include "byte_queue.h"
#include <stdio.h>
#include "typedef.h"


static void initUart(int32 baudrate) {
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;  //定义串口初始化结构体
  NVIC_InitTypeDef NVIC_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
  /*  USART1_TX -> PA9 */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;	       //选中串口默认输出管脚         
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //定义输出最大速率 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;//定义管脚9的模式  
  GPIO_Init(GPIOA, &GPIO_InitStructure);           //调用函数，把结构体参数输入进行初始化		   
  /*  USART1_RX ->	PA10*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  USART_InitStructure.USART_BaudRate = baudrate; //波特率
  USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位8位
  USART_InitStructure.USART_StopBits = USART_StopBits_1;	//停止位1位
  USART_InitStructure.USART_Parity = USART_Parity_No;		//校验位 无
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无流控制
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;		//使能接收和发送引脚

  USART_Init(USART1, &USART_InitStructure); //将以上赋完值的结构体带入库函数USART_Init进行初始化

  // 配置 NVIC 以使能 USART1 中断
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);  
  
  USART_Cmd(USART1, ENABLE);//开启USART1，注意与上面RCC_APB2PeriphClockCmd()设置的区别
}

static uint8 tx_buf[256];
static sByteQueue u1tx_queue;

static void initQueue(void) {
  //初始化这两个队列
  ByteQueue_init(&u1tx_queue, tx_buf, 256);
}

static void sendByte(uint8 data) {
  __disable_irq();
  ByteQueue_enqueue(&u1tx_queue, data);
  __enable_irq();
  USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
}

void Print_init(int32 baudrate) {
  initUart(baudrate);
  initQueue();
}

int fputc(int ch, FILE* f) {
  sendByte(ch);
  return 0;
}

void USART1_IRQHandler(void) {
  if (USART_GetITStatus(USART1, USART_IT_TXE)) {//TX buff空中断
    //从缓冲区取出数据
    int16 data = ByteQueue_dequeue(&u1tx_queue);
    if (data >= 0) {
      USART_SendData(USART1, (unsigned char)data);
    } else {
      USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
    }
  }
}


